﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Solvers;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        List<StackPanel> lista;
        int row = 1, col = 1;
        int g1 = 0, g2 = 0;
        float max1 = 0, max2 = 0;
        Thickness margin = new Thickness(4, 4, 4, 4);

        public MainWindow()
        {
            InitializeComponent();
            lista = new List<StackPanel>();
            StackPanel sP = new StackPanel();
            sP.Orientation = Orientation.Horizontal;
            sP.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            lista.Add(sP);
            TextBox tb = new TextBox();
            tb.Height = 30;
            tb.Width = 30;
            tb.Margin = margin;
            tb.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
            tb.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
            lista[0].Children.Add(tb);
            sPanel.Children.Add(lista[0]);

            addCol();
            //            addCol();
            addRow();
            //            addRow();
        }

        private void colBut_Click(object sender, RoutedEventArgs e)
        {
            addCol();
        }

        private void addCol()
        {
            foreach (StackPanel stkPnl in lista)
            {
                TextBox tb = new TextBox();
                tb.Height = 30;
                tb.Width = 30;
                tb.Margin = margin;
                tb.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
                tb.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
                stkPnl.Children.Add(tb);
            }
            col++;
        }

        private void rowBut_Click(object sender, RoutedEventArgs e)
        {
            addRow();
        }

        private void addRow()
        {
            StackPanel sP = new StackPanel();
            sP.Orientation = Orientation.Horizontal;
            sP.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            for (int i = 0; i < col; i++)
            {
                TextBox tb = new TextBox();
                tb.Height = 30;
                tb.Width = 30;
                tb.Margin = margin;
                tb.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
                tb.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
                sP.Children.Add(tb);
            }
            lista.Add(sP);
            row++;
            sPanel.Children.Add(sP);
        }

        private void oblBut_Click(object sender, RoutedEventArgs e)
        {
            float[,] tab = new float[row, col];
            int i = 0, j = 0;
            Boolean noVal = false;
            foreach (StackPanel stP in lista)
            {
                j = 0;
                foreach (TextBox tb in stP.Children)
                {
                    tb.Background = Brushes.White;
                    try
                    {
                        tab[i, j] = Convert.ToSingle(tb.Text);
                    }
                    catch (System.FormatException)
                    {
                        tb.Background = Brushes.Crimson;
                        noVal = true;
                    }
                    j++;
                }
                i++;
            }



            if (!noVal)
            {
                gracz1(tab);
                gracz2(tab);
                if (g1 == g2)
                {
                    wyswietlenie();
                }
                else
                {
                    //tab = usuniecieZdominowanych(tab);
                    //tab = usuniecieZdominowanych2(odrwTab(tab));
                    //tab = odrwTab(tab);
                    simplex(tab, true);
                    tab = odrwTab(tab);
                    tab = negTab(tab);
                    simplex(tab, false);
                }
            }
        }

        private float[,] negTab(float[,] tab)
        {
            float max = tab[0, 0];
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    if (tab[i, j] > max)
                        max = tab[i, j];
                }
            }

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                        tab[i,j] = max - tab[i, j];
                }
            }

            return tab;
        }

        private float[,] usuniecieZdominowanych(float[,] tab)
        {
            List<int> usun = new List<int>();

            for (int i = 0; i < row; i++)
            {
                for (int m = 0; m < col; m++)
                {
                    int pom = 0;
                    for (int j = 0; j < col; j++)
                    {
                        if (m < row)
                        {
                            if (tab[m, j] > tab[i, j])
                            {
                                pom++;
                                if (pom == col)
                                {
                                    usun.Add(i);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }

            float[,] tab2 = new float[row - usun.Count, col];

            int row2 = 0;
            for (int i = 0; i < row; i++)
            {
                if (!usun.Contains(i))
                {
                    for (int j = 0; j < col; j++)
                    {
                        tab2[row2, j] = tab[i, j];
                    }
                    row2++;
                }
            }

            this.row = row - usun.Count;

            int b = 0;
            foreach (StackPanel stP in lista)
            {
                int j = 0;
                foreach (TextBox tb in stP.Children)
                {
                    if (usun.Contains(b))
                        tb.Background = Brushes.LightPink;
                    j++;
                }
                b++;
            }
            //foreach (int ok in usun)
            //{
            //    System.Console.WriteLine(ok);
            //}
            return tab2;
        }

        private float[,] usuniecieZdominowanych2(float[,] tab)
        {
            List<int> usun = new List<int>();

            for (int i = 0; i < row; i++)
            {
                for (int m = 0; m < col; m++)
                {
                    int pom = 0;
                    for (int j = 0; j < col; j++)
                    {
                        if (m < row)
                        {
                            if (tab[m, j] > tab[i, j])
                            {
                                pom++;
                                if (pom == col)
                                {
                                    usun.Add(i);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }

            float[,] tab2 = new float[row - usun.Count, col];

            int row2 = 0;
            for (int i = 0; i < row; i++)
            {
                if (!usun.Contains(i))
                {
                    for (int j = 0; j < col; j++)
                    {
                        tab2[row2, j] = tab[i, j];
                    }
                    row2++;
                }
            }

            this.row = row - usun.Count;

            int b = 0;
            foreach (StackPanel stP in lista)
            {
                int j = 0;
                foreach (TextBox tb in stP.Children)
                {
                    if (usun.Contains(j))
                        tb.Background = Brushes.LightPink;
                    j++;
                }
                b++;
            }
            //foreach (int ok in usun)
            //{
            //    System.Console.WriteLine(ok);
            //}
            return tab2;
        }

        private float[,] odrwTab(float[,] tab)
        {

            float[,] tab2 = new float[col, row];

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    tab2[j, i] = tab[i, j];
                }
            }

            int row2 = row;
            int col2 = col;
            col = row2;
            row = col2;

            return tab2;
        }

        private void simplex(float[,] tab, Boolean xory)
        {
            SimplexSolver solver = new SimplexSolver();
            int[] x = new int[col];
            int[] y = new int[row];

            for (int i = 0; i < col; i++)
            {
                solver.AddVariable("x" + i, out x[i]);
                solver.SetBounds(x[i], 1, 2);
            }

            for (int i = 0; i < row; i++)
            {
                solver.AddRow("y" + i, out y[i]);
                solver.SetBounds(y[i], 1, 2);
            }

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    System.Console.Write(tab[i, j]);
                    solver.SetCoefficient(y[i], x[j], Convert.ToSingle(tab[i, j]));
                }
            }

            solver.Solve(new SimplexSolverParams());

            double suma = 0;

            for (int i = 0; i < row; i++)
            {
                suma += solver.GetValue(y[i]).ToDouble();
            }

            for (int i = 0; i < row; i++)
            {
                if (xory)
                    lab1.Content = lab1.Content + " x" + i + ": " + (solver.GetValue(y[i]).ToDouble()/suma);
                else
                    lab2.Content = lab2.Content + " y" + i + ": " + (solver.GetValue(y[i]).ToDouble()/suma);
            }
        }

        private void gracz1(float[,] tab)
        {
            float[] tab2 = new float[row];
            for (int i = 0; i < row; i++)
            {
                tab2[i] = tab[i, 0];
                for (int j = 0; j < col; j++)
                {
                    if (tab[i, j] < tab2[i])
                        tab2[i] = tab[i, j];
                }
            }

            float max = tab2[0];
            g1 = 0;
            for (int i = 0; i < row; i++)
            {
                if (tab2[i] > max)
                {
                    max = tab2[i];
                    max1 = max;
                    g1 = i;
                }
            }
        }

        private void gracz2(float[,] tab)
        {
            float[] tab2 = new float[col];
            for (int i = 0; i < col; i++)
            {
                tab2[i] = tab[0, i];
                for (int j = 0; j < row; j++)
                {
                    if (tab[j, i] > tab2[i])
                        tab2[i] = tab[j, i];
                }
            }

            float max = tab2[0];
            g2 = 0;
            for (int i = 0; i < col; i++)
            {
                if (tab2[i] < max)
                {
                    max = tab2[i];
                    max2 = max;
                    g2 = i;
                }
            }
        }

        private void wyswietlenie()
        {
            int i = 0, j = 0;

            if (max1 == max2)
            {
                foreach (StackPanel stP in lista)
                {
                    j = 0;
                    foreach (TextBox tb in stP.Children)
                    {
                        if (i == g1 && j == g2)
                            tb.Background = Brushes.LightPink;
                        else if (i == g1)
                            tb.Background = Brushes.LightBlue;
                        else if (j == g2)
                            tb.Background = Brushes.LightGreen;
                        j++;
                    }
                    i++;
                }
            }
        }
    }
}